package gui;

import file.LeitorArquivoIsra;
import gui.tools.ClippingToolItem;
import gui.tools.MoveToolItem;
import gui.tools.ResizeToolItem;
import gui.tools.RotateToolItem;
import gui.tools.ToolItem;
import gui.tools.VectorialLineToolItem;
import gui.tools.VectorialRectToolItem;
import gui.tools.VectorialSelectionToolItem;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

import tools.vetorial.DeleteObjectTool;
import core.DrawCanvas;
import core.VectorialObject;

public class MainFrame extends JFrame{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private DrawCanvas canvas;
	
	private JScrollPane pnlCanvas;
	
	private JPanel pnlTools;
	
	private JPanel pnlAdjust;
	
	private JPanel pnlLeft;
	
	private JMenuBar menuBar;
	
	private JMenu menuArquivo;
	
	private HashMap<String, ToolItem> toolItens = new HashMap<String, ToolItem>();
	
	private ButtonGroup btnGroup = new ButtonGroup();
	
	private File file = null;
	
	private boolean saved = false;
	
	private ImageSetup mImageSetup = new ImageSetup();
	
	public MainFrame(){
		init();

//		installToolItem(new SelectionToolItem());
//		installToolItem(new PencilToolItem());
//		installToolItem(new BucketFillToolItem());
//		installToolItem(new StraightLineToolItem());
//		installToolItem(new EllipseToolItem());
//		installToolItem(new RectToolItem());
//		installToolItem(new TextboxToolItem());
		installToolItem(new	VectorialSelectionToolItem());
		installToolItem(new VectorialLineToolItem());
		installToolItem(new VectorialRectToolItem());
		installToolItem(new MoveToolItem());
		installToolItem(new RotateToolItem());
		installToolItem(new ClippingToolItem());
		installToolItem(new ResizeToolItem());
		
		canvas.addSelectionAwareTool(new DeleteObjectTool());

	}
	
	protected void init(){
		
		mImageSetup.setSize(new Dimension(200,150));
		
		pnlTools = new JPanel();
		
		pnlAdjust = new JPanel();
		
		pnlTools.setLayout(new FlowLayout());
		
		pnlTools.setPreferredSize(new Dimension(60,130));
		
		pnlAdjust.setLayout(new BorderLayout());
		
		canvas = new DrawCanvas();
		canvas.setPreferredSize(new Dimension(400,400));
		canvas.addSelectionListener(listener);
		
		pnlCanvas = new JScrollPane(canvas);
		pnlCanvas.setBackground(Color.lightGray);
		
		pnlLeft = new JPanel();
		
		pnlLeft.setBackground(SystemColor.control);
		pnlTools.setBackground(SystemColor.control);
		pnlAdjust.setBackground(SystemColor.control);
		
		pnlLeft.setLayout(new FlowLayout());
		
		pnlLeft.add(pnlTools);
		pnlLeft.add(pnlAdjust);
		
		pnlLeft.setBorder(BorderFactory.createEtchedBorder());
		pnlLeft.setPreferredSize(new Dimension(100, 100));
		
		GridBagLayout mLayout = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		
		setLayout(mLayout);
		
		c.gridx = 0;
		c.gridy = 0;
		c.weightx = 0;
		c.weighty = 1;
		c.fill = GridBagConstraints.BOTH;
		add(pnlLeft, c);
		
		c.gridx = 1;
		c.gridy = 0;
		c.weightx = 1;
		c.weighty = 1;
//		c.fill = GridBagConstraints.BOTH;
		add(pnlCanvas, c);
		
		setupMenuBar();
		updateTitle();
		
	}
	
	protected void setupMenuBar(){
		
		menuBar = new JMenuBar();
		
		menuArquivo = new JMenu("Arquivo");
		
		menuBar.add(menuArquivo);
		
		menuArquivo.add(actNovo);
		
		menuArquivo.add(actSave);
		
		menuArquivo.add(actAbrir);
		
		this.setJMenuBar(menuBar);
		
	}
	
	public void installToolItem(ToolItem ti){
		
		if(toolItens.containsKey(ti.getName())){
			return;
		}
		
		toolItens.put(ti.getName(), ti);
		
		JToggleButton btn = new JToggleButton(ti.getIcon());
		
		btn.setName(ti.getName());
		
		btn.setMargin(new Insets(0, 0, 0, 0));
		
		pnlTools.add(btn);
		btnGroup.add(btn);
		
		if(ti.getPropertiesEditor() != null) {
			ti.getPropertiesEditor().setBackground(SystemColor.control);
			ti.getPropertiesEditor().setBorder(
					BorderFactory.createCompoundBorder( 
							BorderFactory.createEtchedBorder(),
							BorderFactory.createEmptyBorder(10, 10, 10, 10)));
		}
		
		btn.addActionListener(toolItensAction);
		
	}
	
	public void selectTool(String name){
	
		ToolItem item = toolItens.get(name);
		
		canvas.setDrawTool(item.getTool());
		
		pnlAdjust.removeAll();
		
		if(item.getPropertiesEditor() != null){
			pnlAdjust.add(item.getPropertiesEditor(), BorderLayout.CENTER);
		}
		
		SwingUtilities.updateComponentTreeUI(pnlLeft);
	}
	
	private ActionListener toolItensAction = new ActionListener() {
		
		@Override
		public void actionPerformed(ActionEvent e) {
			
			if(!(e.getSource() instanceof JToggleButton)){
				return;
			}
			
			JToggleButton src = (JToggleButton) e.getSource();
			
			selectTool(src.getName());
		}
	};
	
	private AbstractAction actSave = new ActSalvar();
	
	private AbstractAction actAbrir = new ActAbrir();
	
	private AbstractAction actNovo = new ActNovo();
	
	private class ActSalvar extends AbstractAction{

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public ActSalvar(){
			
			this.putValue(SMALL_ICON, new ImageIcon(
					MainFrame.class.getResource("/imagens/filesave_16x16.png")));
			
			this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl + s"));
			
			this.putValue(NAME, "Salvar");
			
		}
		
		@Override
		public void actionPerformed(ActionEvent e) {
		
			if(file == null){
				selectFile();
			}
			
			if(file != null){
				saveImage();
			}
		}
	};
	
	private class ActAbrir extends AbstractAction{
		
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public ActAbrir(){
			
			this.putValue(SMALL_ICON, new ImageIcon(
					MainFrame.class.getResource("/imagens/fileopen_16x16.png")));
			
			this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl+s"));
			
			this.putValue(NAME, "Abrir");
			
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			JFileChooser fc = new JFileChooser(new File(System.getProperty("user.home")));
			
			fc.setDialogTitle("Abrir arquivo.");
			
			if(fc.showDialog(MainFrame.this, "Abrir") != JFileChooser.APPROVE_OPTION){
				return;
			}
			
			file = fc.getSelectedFile();
			
			openImage();
		}
		
	}
	
	private class ActNovo extends AbstractAction{
		
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public ActNovo(){
			
			this.putValue(SMALL_ICON, new ImageIcon(
					MainFrame.class.getResource("/imagens/new_16x16.png")));
			
			this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl+n"));
			
			this.putValue(NAME, "Novo");
			
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			mImageSetup.setVisible(true);
			
			if(mImageSetup.getReturn() == ImageSetup.CONFIRM) {
				int width = (int)mImageSetup.getSelectedWidth();
				int height = (int)mImageSetup.getSelectedHeight();
				canvas.newImage(width, height);
				canvas.setPreferredSize(new Dimension(width, height));
			}
		}
		
	}
	
	private void selectFile(){
		JFileChooser fc = new JFileChooser(new File(System.getProperty("user.home")));
		
		fc.setDialogTitle("Salvar arquivo.");
		
		if(file == null){
			if(fc.showDialog(MainFrame.this, "Salvar") != JFileChooser.APPROVE_OPTION){
				return;
			}
		}
		
		file = fc.getSelectedFile();
	}
	
	private void saveImage(){
		
		try {
			ImageIOUtils.saveImage(canvas.getBufferImage(), file);
			
			saved = true;
			
			updateTitle();
			
		} catch (IOException e1) {
			JOptionPane.showMessageDialog(
					MainFrame.this, e1.toString(),
					"Erro ao salvar imagem", JOptionPane.ERROR_MESSAGE);
		}
		
	}
	
	private void openImage(){
		
		try {
			VectorialObject vectorial = LeitorArquivoIsra.parse(file);
	
			canvas.getDrawContext().addObject2d(vectorial);
			canvas.getDrawContext().setChanged(true);

		} catch (Exception e) {
			JOptionPane.showMessageDialog(
					MainFrame.this, e.toString(),
					"Erro ao salvar imagem", JOptionPane.ERROR_MESSAGE);
		}
		
	}
	
	public void setFile(File file){
		
		this.file = file;
		
		if(this.file != null){
			updateTitle();
		}
	}
	
	private void updateTitle(){
		
		String title = "PENTE";
		
		if(file != null){
			title += " - " + file.toString() + (saved? "" : "*");
		}
		
		setTitle(title);
		
	}
	
	public static void main(String args[]){
		
		JFrame frm = new MainFrame();
	
		frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frm.setSize(600,600);
		frm.setVisible(true);
		
	}
	
	private DrawCanvas.SelectionListener listener = new DrawCanvas.SelectionListener() {
		
		@Override
		public void onSelection(List<VectorialObject> vo) {
			for(java.util.Map.Entry<String, ToolItem> entry : toolItens.entrySet()) {
				if(entry.getValue() instanceof ToolItem) {
					entry.getValue().onSelection(vo);
				}
			}
		}
	};
}
